package com.hxzy.common.util;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * 脱敏工具类
 * 隐藏某些名称词汇
 * @author:
 */
public class SecretUtil {
    public static final String PASSWORD_KEY="password";


    /**
     * 处理日志字符串，返回脱敏后的字符串
     * @param message 被脱敏字符串
     * @param secritKey 需要脱敏的字符串key
     * @return
     */
    public static String invokeMsg(String secritKey, String message){
        String msg = new String(message);
        //处理字符串
        if(secritKey!=null && secritKey.length()>0){
            String[] keyArr = secritKey.split(",");
            for(String key: keyArr){
                // 找key
                int index= -1;
                do{
                    index = msg.indexOf(key, index+1);
                    if(index!=-1){
                        // 判断key是否为单词字符
                        if(isWordChar(msg,key,index)){
                            continue;
                        }
                        // 确定是单词无疑....................................
                        // 寻找值的开始位置.................................
                        int valueStart = getValueStartIndex(msg,index + key.length());

                        //查找值的结束位置（逗号，分号）........................
                        int valueEnd = getValuEndEIndex(msg,valueStart);

                        // 对获取的值进行脱敏
                        String subStr = msg.substring(valueStart, valueEnd);
                        //密码进行全脱敏
                        if(key.toLowerCase().contains(PASSWORD_KEY) ||subStr.length()<=8){
                            subStr = secret(subStr,0,50);
                        }else {
                            //隐藏中间4位
                            subStr = secret(subStr,5,8);
                        }

                        ///////////////////////////
                        msg = msg.substring(0,valueStart) + subStr + msg.substring(valueEnd);
                    }
                }while(index!=-1);

            }
        }
        return msg;
    }


    private static Pattern pattern = Pattern.compile("[0-9a-zA-Z]");
    /**
     * 判断从字符串msg获取的key值是否为单词 ， index为key在msg中的索引值
     * @return
     */
    private static boolean isWordChar(String msg,String key, int index){

        // 必须确定key是一个单词............................
        if(index!=0){ //判断key前面一个字符
            char preCh = msg.charAt(index-1);
            Matcher match = pattern.matcher(preCh+"");
            if(match.matches()){
                return true;
            }
        }
        //判断key后面一个字符
        char nextCh = msg.charAt(index+key.length());
        Matcher match = pattern.matcher(nextCh+"");
        if(match.matches()){
            return true;
        }

        return false;

    }

    /**
     * 获取value值的开始位置
     * @param msg 要查找的字符串
     * @param valueStart 查找的开始位置
     * @return
     */
    private static int getValueStartIndex(String msg, int valueStart ){
        // 寻找值的开始位置.................................
        do{
            char ch = msg.charAt(valueStart);
            // key 与 value的分隔符
            if(ch == ':' || ch == '='){
                valueStart ++;
                ch = msg.charAt(valueStart);
                valueStart ++;

                break;
            }else{
                valueStart ++;
            }

        }while(true);
        return valueStart;
    }

    /**
     * 获取value值的结束位置
     * @return
     */
    private static int getValuEndEIndex(String msg,int valueEnd){

        do{
            if(valueEnd == msg.length()){
                break;
            }
            char ch = msg.charAt(valueEnd);
            // 引号时，判断下一个值是结束，分号还是逗号决定是否为值的结束
            if(ch == '"' || ch=='\''){
                if(valueEnd+1 == msg.length()){
                    break;
                }
                char nextCh = msg.charAt(valueEnd+1);
                if(nextCh ==';' || nextCh == ',' || nextCh =='}'||nextCh ==']'){
                    // 去掉前面的 \  处理这种形式的数据 "account_num\\\":\\\"6230958600001008\\\"
                    while(valueEnd>0 ){
                        char preCh = msg.charAt(valueEnd-1);
                        if(preCh != '\\'){
                            break;
                        }
                        valueEnd--;
                    }
                    break;
                }else{
                    valueEnd ++;
                }
            }else if (ch ==';' || ch == ','){
                break;
            }else{
                valueEnd ++;
            }

        }while(true);

        return valueEnd;
    }


    /**
     * 处理需要隐藏的字符串
     * @param submsg value
     * @param start 起始位置
     * @param end 结束位置
     * @return
     */
    private static String secret(String submsg,int start,int end){
        StringBuffer sbResult = new StringBuffer();
        if(submsg!=null && submsg.length()>0){
            int len = submsg.length();
            for(int i = len-1;i>=0;i--){
                if(len-i<start || len-i>end){
                    sbResult.insert(0, submsg.charAt(i));
                }else{
                    sbResult.insert(0, '*');
                }
            }
        }
        return sbResult.toString();
    }

}
